home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / AX_MBX.C < prev    next >
C/C++ Source or Header  |  1990-08-07  |  33KB  |  1,395 lines

  1. /* ax.25 mailbox by w9nk */
  2. /* adapted to CHLNET environment by PE1CHL */
  3. /* outbound forwarding to AX.25 BBS systems added by PE1CHL */
  4.  
  5. #include <stdio.h>
  6. #include <time.h>
  7. #include <ctype.h>
  8. #ifdef    UNIX
  9. #include <sys/types.h>
  10. #endif
  11. #include "global.h"
  12. #include "mbuf.h"
  13. #include "ax25.h"
  14. #include "timer.h"
  15. #include "iface.h"
  16. #include "lapb.h"
  17. #include "smtp.h"
  18. #include "ax_mbx.h"
  19. #include "cmdparse.h"
  20.  
  21. /* #define MBDEBUG */
  22.  
  23. static char mbmenu[]    = "(B)ye, (I)nfo, (S)end >\r";
  24. static char mbprompt[]    = ">\r";
  25. static char mbok[]    = "OK\r";
  26. static char mbno[]    = "NO\r";
  27. static char mberr[]    = "Huh?\r";
  28. static char mbserr[]    = "S command syntax error - format is:\r  S name [@ host] [< from_addr] [$bulletin_id]\r";
  29. static char mbbaduser[] = "Bad user or host name\r";
  30. static char mbsubject[] = "Subject:\r";
  31. static char mbmesg[]    = "Enter message.  Terminate with /EX or ^Z in first column:\r";
  32. static char mbtemp[]    = "Can't create temp file for mail\r";
  33. static char mbqerr[]    = "Couldn't queue message for delivery\r";
  34. static char mbbye[]    = "Goodbye!\r";
  35. static char mbcr[]    = "\r";
  36.  
  37. extern char hostname[];
  38.  
  39. char mbxinfofile[80] = "";
  40. static struct mbx *fwdmbx;        /* currently-connecting mbx */
  41.  
  42. static int mbx_line(),mbx_sid(),mbx_script();
  43. static void mbx_rx(),mbx_tx(),mbx_send(),mbx_doscript();
  44. void mbxfwd();
  45.  
  46. static int dombxconnect();
  47. struct cmds fwdcmds[] = {
  48.     "connect",    dombxconnect,    3,    NULLCHAR,    NULLCHAR,
  49.     NULLCHAR,    NULLFP,        0,    NULLCHAR,    NULLCHAR
  50. };
  51.  
  52. extern char *getnenv();
  53. extern char *strstr();
  54.  
  55. /* find mbx struct for specified axp */
  56.  
  57. static struct mbx *
  58. find_mbx(axp)
  59. register struct ax25_cb *axp;
  60. {
  61.     register struct mbx *m;
  62.  
  63.     for (m = (struct mbx *) ((struct ax25_call *) axp->user)->user;
  64.          m != NULLMBX; m = m->next) {
  65.         if(m->ax25_cb == axp)
  66.             break;
  67.     }
  68.  
  69.     return m;
  70. }
  71.  
  72. /* State-change upcall handler for mailbox */
  73.  
  74. void
  75. mbx_state(axp,old,new,msg)
  76. register struct ax25_cb *axp;
  77. int old,new,msg;
  78.  
  79. {
  80.     register struct mbx *m;
  81.     char *cp;
  82.     struct mbxpath *mbp;
  83.     char mesg[160];
  84.  
  85.     switch (new)
  86.     {
  87.     case CONNECTED:
  88. #ifdef MBDEBUG
  89.         printf("MBX: connected\n");
  90. #endif
  91.         /* check if station already known, and register if not */
  92.         if((m = find_mbx(axp)) == NULLMBX) {
  93.         if((m = (struct mbx *) calloc(1,sizeof(struct mbx))) == NULLMBX) {
  94.             axp->state = DISCONNECTED;    /* send DM */
  95.             return;
  96.         }
  97.  
  98.         /* connect the user to this mbox's user list */
  99.         if((m->next = (struct mbx *) ((struct ax25_call *) axp->user)->user)
  100.              != NULLMBX)
  101.             m->next->prev = m;
  102.  
  103.         ((struct ax25_call *) axp->user)->user = (char *) m;
  104.         m->ax25_cb = axp;
  105.  
  106.         pax25(m->name,&axp->addr.dest);
  107.         cp = index(m->name,'-');
  108.         if (cp != NULLCHAR)        /* get rid of SSID */
  109.             *cp = '\0';
  110.         for (cp = m->name; *cp != '\0'; cp++)
  111.             *cp = tolower(*cp);        /* convert to lowercase */
  112.  
  113.         axp->r_upcall = mbx_rx;
  114.         axp->t_upcall = mbx_tx;
  115. #ifdef MBDEBUG
  116.         printf("MBX: new user %s\n",m->name);
  117. #endif
  118.         log_ax(axp,"Conn to mbox");
  119.  
  120.         sprintf(mesg,"%c[NET-$]\rWelcome to the %s TCP/IP Mailbox\r%s",
  121.                  PID_FIRST|PID_LAST|PID_NO_L3,hostname,mbmenu);
  122.  
  123.         enqueue(&axp->txq,qstring(mesg));
  124.         }
  125.  
  126.         /* send first message when script starts with "s" */
  127.         if (m->state == MBX_CONN)
  128.         mbx_tx(axp,1);
  129.  
  130.         break;
  131.  
  132.     case DISCONNECTED:
  133.         if ((m = find_mbx(axp)) == NULLMBX)
  134.         break;
  135.  
  136.         if(m->prev != NULLMBX)
  137.         m->prev->next = m->next;
  138.         else
  139.         ((struct ax25_call *) axp->user)->user = (char *) m->next;
  140.  
  141.         if(m->next != NULLMBX)
  142.         m->next->prev = m->prev;
  143.  
  144.         if (m->to != NULLCHAR)
  145.         free(m->to);
  146.  
  147.         if (m->tofrom != NULLCHAR)
  148.         free(m->tofrom);
  149.  
  150.         if (m->tomsgid != NULLCHAR)
  151.         free(m->tomsgid);
  152.  
  153.         if (m->fullfrom != NULLCHAR)
  154.         free(m->fullfrom);
  155.  
  156.         if (m->subject != NULLCHAR)
  157.         free(m->subject);
  158.  
  159.         while (m->mbpath != NULLMBXPATH) {
  160.         mbp = m->mbpath->next;
  161.         free(m->mbpath);
  162.         m->mbpath = mbp;
  163.         }
  164.  
  165.         if (m->tfile != NULLFILE)
  166.         fclose(m->tfile);
  167.  
  168.         if (m->script != NULLFILE)
  169.         fclose(m->script);
  170.  
  171.         if (m->smtp_cb != NULLCB)
  172.         if (m->state == MBX_DISC) {    /* expecting DISC? */
  173. #ifdef MBDEBUG
  174.             printf("MBX: mbx_state calls mbxfwd\n");
  175. #endif
  176.             mbxfwd(m->smtp_cb);        /* then, start fwd to next box */
  177.         } else {
  178. #ifdef MBDEBUG
  179.             printf("MBX: mbx_state calls del_session\n");
  180. #endif
  181.             del_session(m->smtp_cb);    /* no, wait a while */
  182.         }
  183.  
  184.         free(m);
  185.         break;
  186.     }
  187. }
  188.  
  189. /* receive upcall for ax.25 */
  190.  
  191. static void mbx_rx(axp,cnt)
  192. struct ax25_cb *axp;
  193. int16 cnt;
  194. {
  195.     struct mbx *m;
  196.     struct mbuf *bp;
  197.     char line[MBXLINE + 1];
  198.     struct mbuf *recvl_ax25();
  199.  
  200.     if((m = find_mbx(axp)) == NULLMBX) {
  201.         disc_ax25(axp);            /* who are you?? */
  202.         return;
  203.     }
  204.  
  205.     while((bp = recvl_ax25(axp,0)) != NULLBUF){ /* get a line of text */
  206.         line[pullup(&bp,line,sizeof(line) - 1)] = '\0';
  207.         rip(line);
  208.         free_p(bp);
  209.         if(mbx_line(m,line) == -1)        /* evaluate inputline */
  210.         break;                /* quit after "bye" */
  211.     }
  212. }
  213.  
  214. /* transmit upcall (used to send a file/mail) */
  215.  
  216. static void
  217. mbx_tx(axp,cnt)
  218. struct ax25_cb *axp;
  219. int16 cnt;
  220. {
  221.     struct mbx *m;
  222.     int remain;
  223.     char *pac;
  224.     char line[MBXLINE + 1];
  225.  
  226.     if((m = find_mbx(axp)) == NULLMBX) {
  227.         disc_ax25(axp);            /* who are you?? */
  228.         return;
  229.     }
  230.  
  231.     switch (m->state)
  232.     {
  233.     case MBX_CONN:                /* connecting? */
  234.     case MBX_SEND:                /* transferring mail? */
  235.         mbx_doscript(m);            /* keep it going */
  236.         break;
  237.  
  238.     case MBX_INFO:                /* sending info? */
  239.     case MBX_BODY:                /* sending mail body? */
  240.         if (m->tfile != NULLFILE) {
  241.         if ((remain = axp->maxframe - len_q(axp->txq)) < 2)
  242.             pac = NULLCHAR;
  243.         else
  244.             if ((pac = malloc(axp->paclen)) != NULLCHAR)
  245.             pac[0] = '\0';        /* clean packet buffer */
  246.  
  247.         while (fgets(line,sizeof(line),m->tfile) != NULLCHAR) {
  248.             rip(line);
  249.             strcat(line,mbcr);
  250.  
  251.             if (pac == NULLCHAR) {
  252.             mbx_msg(m,line);
  253.             remain--;
  254.             } else {
  255.             if ((strlen(pac) + strlen(line)) < axp->paclen){
  256.                 strcat(pac,line);    /* still fits, concat it */
  257.                 continue;        /* read next line */
  258.             }
  259.             if (pac[0] != '\0'){
  260.                 mbx_msg(m,pac);    /* too long, flush old */
  261.                 remain--;
  262.             }
  263.             strcpy(pac,line);
  264.             }
  265.  
  266.             /* when only one packet left in window, stop buffering */
  267.             if (remain < 2 && pac != NULLCHAR){
  268.             if (pac[0] != '\0'){
  269.                 mbx_msg(m,pac);
  270.                 remain--;
  271.             }
  272.             free(pac);
  273.             pac = NULLCHAR;
  274.             }
  275.  
  276.             if (remain <= 0)
  277.             return;            /* window full, pause */
  278.         }
  279.         fclose(m->tfile);
  280.         m->tfile = NULLFILE;
  281.  
  282.         /* don't forget buffered packet */
  283.         if (pac != NULLCHAR){
  284.             if (pac[0] != '\0')
  285.             mbx_msg(m,pac);
  286.             free(pac);
  287.         }
  288.  
  289.         /* got EOF, see what to do next.  when INFO: ->command state */
  290.         /* when BODY: send end-of-message and back to SEND state */
  291.         if (m->state == MBX_INFO) {
  292.             m->state = MBX_CMD;
  293.             mbx_msg(m,(m->sid & MBX_SID) ? mbprompt : mbmenu);
  294.         } else {
  295.             m->state = MBX_SEND;
  296.             if (m->sline[1] == '\0')
  297.             strcpy(m->sline + 1,"\032"); /* default ^Z */
  298.             strcat(m->sline,mbcr);
  299.             mbx_msg(m,m->sline + 1);
  300.             if (mbx_script(m) == 0)
  301.             mbx_doscript(m);
  302.         }
  303.         }
  304.         break;
  305.     }
  306. }
  307.  
  308. /* process one line for the mailbox */
  309.  
  310. static int
  311. mbx_line(m,line)
  312. struct mbx *m;
  313. char *line;
  314. {
  315.     switch (m->state)
  316.     {
  317.     case MBX_CMD:
  318.     switch (tolower(line[0])) {
  319.         case 'b':                /* bye - bye */
  320.         if (!(m->sid & MBX_SID))
  321.            mbx_msg(m,mbbye);
  322.         close_ax25(m->ax25_cb);
  323.         return -1; /* tell line processor to quit */
  324.  
  325.         case 'i': {                /* info */
  326.         if (mbxinfofile[0] == '\0' ||
  327.             (m->tfile = fopen(mbxinfofile,"r")) == NULLFILE)
  328.             mbx_msg(m,(m->sid & MBX_SID) ? mbprompt : mbmenu);
  329.         else {
  330.             m->state = MBX_INFO;
  331.             mbx_tx(m->ax25_cb,1);
  332.         }
  333.         }
  334.         break;
  335.  
  336.         case 's': {
  337.         int badsubj = 0;
  338.  
  339.         /* Get S-command type (B,P,T, etc.) */
  340.  
  341.         if (line[1] == '\0')
  342.             m->stype = ' ';
  343.         else
  344.             m->stype = toupper(line[1]);
  345.  
  346.         if (mbx_to(m,line) == -1) {
  347.             if (m->sid & MBX_SID)
  348.             mbx_msg(m,mb